<template>
  <div class="table-container" :class="containerClass">
    <!-- 表格工具栏 -->
    <div v-if="showToolbar" class="table-toolbar">
      <div class="table-toolbar-left">
        <!-- 标题 -->
        <h3 v-if="title" class="table-title">{{ title }}</h3>

        <!-- 描述 -->
        <p v-if="description" class="table-description">{{ description }}</p>

        <!-- 选中信息 -->
        <div
          v-if="selectable && selectedRows.length > 0"
          class="table-selection-info"
        >
          已选择 {{ selectedRows.length }} 项
          <Button
            type="secondary"
            variant="text"
            size="small"
            @click="clearSelection"
          >
            清空
          </Button>
        </div>
      </div>

      <div class="table-toolbar-right">
        <slot name="toolbar"></slot>

        <!-- 刷新按钮 -->
        <Button
          v-if="refreshable"
          type="secondary"
          variant="text"
          icon="refresh"
          :loading="loading"
          @click="handleRefresh"
        >
          刷新
        </Button>

        <!-- 列设置 -->
        <Button
          v-if="columnSettable"
          type="secondary"
          variant="text"
          icon="settings"
          @click="showColumnSettings = true"
        >
          列设置
        </Button>
      </div>
    </div>

    <!-- 表格主体 -->
    <div class="table-wrapper" :class="wrapperClass">
      <table class="table" :class="tableClass">
        <!-- 表头 -->
        <thead class="table-header">
          <tr>
            <!-- 选择列 -->
            <th v-if="selectable" class="table-cell table-cell-selection">
              <input
                type="checkbox"
                :checked="isAllSelected"
                :indeterminate="isIndeterminate"
                @change="handleSelectAll"
                class="table-checkbox"
              />
            </th>

            <!-- 序号列 -->
            <th v-if="showIndex" class="table-cell table-cell-index">#</th>

            <!-- 数据列 -->
            <th
              v-for="column in visibleColumns"
              :key="column.key"
              class="table-cell table-cell-header"
              :class="getColumnClass(column)"
              :style="getColumnStyle(column)"
              @click="handleSort(column)"
            >
              <div class="table-header-content">
                <span class="table-header-title">{{ column.title }}</span>

                <!-- 排序图标 -->
                <div v-if="column.sortable" class="table-sort-icon">
                  <Icon
                    :name="getSortIcon(column.key)"
                    :size="14"
                    :class="getSortIconClass(column.key)"
                  />
                </div>

                <!-- 筛选图标 -->
                <Icon
                  v-if="column.filterable"
                  name="filter"
                  :size="14"
                  class="table-filter-icon"
                  :class="{ active: hasFilter(column.key) }"
                  @click.stop="showFilter(column)"
                />
              </div>
            </th>

            <!-- 操作列 -->
            <th v-if="showActions" class="table-cell table-cell-actions">
              操作
            </th>
          </tr>
        </thead>

        <!-- 表体 -->
        <tbody class="table-body">
          <!-- 加载状态 -->
          <tr v-if="loading" class="table-loading-row">
            <td :colspan="totalColumns" class="table-loading-cell">
              <Loading
                :size="loadingSize"
                :type="loadingType"
                text="加载中..."
              />
            </td>
          </tr>

          <!-- 空状态 -->
          <tr v-else-if="!data || data.length === 0" class="table-empty-row">
            <td :colspan="totalColumns" class="table-empty-cell">
              <div class="table-empty">
                <Icon name="inbox" :size="48" class="table-empty-icon" />
                <p class="table-empty-text">{{ emptyText }}</p>
                <slot name="empty"></slot>
              </div>
            </td>
          </tr>

          <!-- 数据行 -->
          <tr
            v-else
            v-for="(row, index) in paginatedData"
            :key="getRowKey(row, index)"
            class="table-row"
            :class="getRowClass(row, index)"
            @click="handleRowClick(row, index)"
            @dblclick="handleRowDoubleClick(row, index)"
          >
            <!-- 选择列 -->
            <td v-if="selectable" class="table-cell table-cell-selection">
              <input
                type="checkbox"
                :checked="isRowSelected(row)"
                @change="handleRowSelect(row, $event)"
                @click.stop
                class="table-checkbox"
              />
            </td>

            <!-- 序号列 -->
            <td v-if="showIndex" class="table-cell table-cell-index">
              {{ getRowIndex(index) }}
            </td>

            <!-- 数据列 -->
            <td
              v-for="column in visibleColumns"
              :key="column.key"
              class="table-cell table-cell-data"
              :class="getColumnClass(column)"
              :style="getColumnStyle(column)"
            >
              <div class="table-cell-content">
                <!-- 自定义渲染 -->
                <slot
                  v-if="$slots[`column-${column.key}`]"
                  :name="`column-${column.key}`"
                  :row="row"
                  :column="column"
                  :index="index"
                  :value="getCellValue(row, column.key)"
                ></slot>

                <!-- 默认渲染 -->
                <span v-else>{{ formatCellValue(row, column) }}</span>
              </div>
            </td>

            <!-- 操作列 -->
            <td v-if="showActions" class="table-cell table-cell-actions">
              <div class="table-actions">
                <slot name="actions" :row="row" :index="index"></slot>
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页 -->
    <div v-if="pagination && !loading" class="table-pagination">
      <div class="table-pagination-info">
        共 {{ total }} 条记录，第 {{ currentPage }} / {{ totalPages }} 页
      </div>

      <div class="table-pagination-controls">
        <Button
          type="secondary"
          variant="outlined"
          size="small"
          :disabled="currentPage <= 1"
          @click="handlePageChange(currentPage - 1)"
        >
          上一页
        </Button>

        <div class="table-pagination-pages">
          <Button
            v-for="page in visiblePages"
            :key="page"
            :type="page === currentPage ? 'primary' : 'secondary'"
            :variant="page === currentPage ? 'filled' : 'text'"
            size="small"
            @click="handlePageChange(page)"
          >
            {{ page }}
          </Button>
        </div>

        <Button
          type="secondary"
          variant="outlined"
          size="small"
          :disabled="currentPage >= totalPages"
          @click="handlePageChange(currentPage + 1)"
        >
          下一页
        </Button>
      </div>
    </div>

    <!-- 列设置弹窗 -->
    <Modal v-model:visible="showColumnSettings" title="列设置" size="small">
      <div class="column-settings">
        <div
          v-for="column in columns"
          :key="column.key"
          class="column-setting-item"
        >
          <input
            type="checkbox"
            :checked="!hiddenColumns.includes(column.key)"
            @change="toggleColumn(column.key)"
          />
          <span>{{ column.title }}</span>
        </div>
      </div>
    </Modal>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import Icon from "./Icon.vue";
import Button from "./Button.vue";
import Loading from "./Loading.vue";
import Modal from "./Modal.vue";

interface TableColumn {
  key: string;
  title: string;
  width?: string | number;
  minWidth?: string | number;
  maxWidth?: string | number;
  align?: "left" | "center" | "right";
  sortable?: boolean;
  filterable?: boolean;
  fixed?: "left" | "right";
  ellipsis?: boolean;
  formatter?: (value: any, row: any) => string;
  className?: string;
}

interface Props {
  // 数据
  data?: any[];
  columns?: TableColumn[];

  // 基础属性
  title?: string;
  description?: string;

  // 样式
  size?: "mini" | "small" | "medium" | "large";
  bordered?: boolean;
  striped?: boolean;
  hoverable?: boolean;

  // 功能
  selectable?: boolean;
  showIndex?: boolean;
  showActions?: boolean;

  // 排序
  sortBy?: string;
  sortOrder?: "asc" | "desc";

  // 分页
  pagination?: boolean;
  pageSize?: number;
  total?: number;

  // 状态
  loading?: boolean;

  // 工具栏
  showToolbar?: boolean;
  refreshable?: boolean;
  columnSettable?: boolean;

  // 其他
  rowKey?: string | ((row: any) => string);
  emptyText?: string;
  loadingSize?: string;
  loadingType?: string;

  // 类名
  containerClass?: string;
  wrapperClass?: string;
  tableClass?: string;
}

const props = withDefaults(defineProps<Props>(), {
  size: "medium",
  hoverable: true,
  showToolbar: true,
  pagination: true,
  pageSize: 10,
  total: 0,
  emptyText: "暂无数据",
  loadingSize: "medium",
  loadingType: "spinner",
});

const emit = defineEmits<{
  refresh: [];
  sort: [column: string, order: "asc" | "desc" | null];
  filter: [column: string, value: any];
  select: [selectedRows: any[]];
  rowClick: [row: any, index: number];
  rowDoubleClick: [row: any, index: number];
  pageChange: [page: number];
}>();

// 响应式数据
const selectedRows = ref<any[]>([]);
const currentPage = ref(1);
const currentSort = ref<{ column: string; order: "asc" | "desc" | null }>({
  column: "",
  order: null,
});
const filters = ref<Record<string, any>>({});
const hiddenColumns = ref<string[]>([]);
const showColumnSettings = ref(false);

// 计算属性
const visibleColumns = computed(() => {
  return (
    props.columns?.filter(
      (column) => !hiddenColumns.value.includes(column.key),
    ) || []
  );
});

const totalColumns = computed(() => {
  let count = visibleColumns.value.length;
  if (props.selectable) count++;
  if (props.showIndex) count++;
  if (props.showActions) count++;
  return count;
});

const sortedData = computed(() => {
  if (!props.data || !currentSort.value.column || !currentSort.value.order) {
    return props.data || [];
  }

  const column = currentSort.value.column;
  const order = currentSort.value.order;

  return [...props.data].sort((a, b) => {
    const aVal = getCellValue(a, column);
    const bVal = getCellValue(b, column);

    if (aVal < bVal) return order === "asc" ? -1 : 1;
    if (aVal > bVal) return order === "asc" ? 1 : -1;
    return 0;
  });
});

const filteredData = computed(() => {
  let data = sortedData.value;

  Object.keys(filters.value).forEach((key) => {
    const filterValue = filters.value[key];
    if (
      filterValue !== undefined &&
      filterValue !== null &&
      filterValue !== ""
    ) {
      data = data.filter((row) => {
        const cellValue = getCellValue(row, key);
        return String(cellValue)
          .toLowerCase()
          .includes(String(filterValue).toLowerCase());
      });
    }
  });

  return data;
});

const paginatedData = computed(() => {
  if (!props.pagination) return filteredData.value;

  const start = (currentPage.value - 1) * props.pageSize;
  const end = start + props.pageSize;
  return filteredData.value.slice(start, end);
});

const totalPages = computed(() => {
  if (!props.pagination) return 1;
  return Math.ceil(filteredData.value.length / props.pageSize);
});

const visiblePages = computed(() => {
  const pages = [];
  const total = totalPages.value;
  const current = currentPage.value;

  if (total <= 7) {
    for (let i = 1; i <= total; i++) {
      pages.push(i);
    }
  } else {
    if (current <= 4) {
      for (let i = 1; i <= 5; i++) {
        pages.push(i);
      }
      pages.push("...", total);
    } else if (current >= total - 3) {
      pages.push(1, "...");
      for (let i = total - 4; i <= total; i++) {
        pages.push(i);
      }
    } else {
      pages.push(1, "...");
      for (let i = current - 1; i <= current + 1; i++) {
        pages.push(i);
      }
      pages.push("...", total);
    }
  }

  return pages;
});

const isAllSelected = computed(() => {
  return (
    paginatedData.value.length > 0 &&
    paginatedData.value.every((row) => isRowSelected(row))
  );
});

const isIndeterminate = computed(() => {
  const selectedCount = paginatedData.value.filter((row) =>
    isRowSelected(row),
  ).length;
  return selectedCount > 0 && selectedCount < paginatedData.value.length;
});

// 方法
const getCellValue = (row: any, key: string) => {
  return key.split(".").reduce((obj, k) => obj?.[k], row);
};

const formatCellValue = (row: any, column: TableColumn) => {
  const value = getCellValue(row, column.key);

  if (column.formatter) {
    return column.formatter(value, row);
  }

  return value ?? "";
};

const getRowKey = (row: any, index: number) => {
  if (typeof props.rowKey === "function") {
    return props.rowKey(row);
  }
  if (typeof props.rowKey === "string") {
    return getCellValue(row, props.rowKey);
  }
  return index;
};

const getRowIndex = (index: number) => {
  return (currentPage.value - 1) * props.pageSize + index + 1;
};

const getRowClass = (row: any, index: number) => {
  return {
    "table-row-selected": isRowSelected(row),
    "table-row-striped": props.striped && index % 2 === 1,
  };
};

const getColumnClass = (column: TableColumn) => {
  return [
    `table-cell-${column.align || "left"}`,
    {
      "table-cell-sortable": column.sortable,
      "table-cell-ellipsis": column.ellipsis,
      "table-cell-fixed-left": column.fixed === "left",
      "table-cell-fixed-right": column.fixed === "right",
    },
    column.className,
  ];
};

const getColumnStyle = (column: TableColumn) => {
  const styles: Record<string, string> = {};

  if (column.width) {
    styles.width =
      typeof column.width === "number" ? `${column.width}px` : column.width;
  }
  if (column.minWidth) {
    styles.minWidth =
      typeof column.minWidth === "number"
        ? `${column.minWidth}px`
        : column.minWidth;
  }
  if (column.maxWidth) {
    styles.maxWidth =
      typeof column.maxWidth === "number"
        ? `${column.maxWidth}px`
        : column.maxWidth;
  }

  return styles;
};

const getSortIcon = (columnKey: string) => {
  if (currentSort.value.column !== columnKey) return "chevron-up-down";
  return currentSort.value.order === "asc" ? "chevron-up" : "chevron-down";
};

const getSortIconClass = (columnKey: string) => {
  return {
    active: currentSort.value.column === columnKey,
  };
};

const hasFilter = (columnKey: string) => {
  return (
    filters.value[columnKey] !== undefined &&
    filters.value[columnKey] !== null &&
    filters.value[columnKey] !== ""
  );
};

const isRowSelected = (row: any) => {
  const rowKey = getRowKey(row, 0);
  return selectedRows.value.some(
    (selectedRow) => getRowKey(selectedRow, 0) === rowKey,
  );
};

// 事件处理
const handleRefresh = () => {
  emit("refresh");
};

const handleSort = (column: TableColumn) => {
  if (!column.sortable) return;

  let order: "asc" | "desc" | null = "asc";

  if (currentSort.value.column === column.key) {
    if (currentSort.value.order === "asc") {
      order = "desc";
    } else if (currentSort.value.order === "desc") {
      order = null;
    }
  }

  currentSort.value = { column: column.key, order };
  emit("sort", column.key, order);
};

const showFilter = (column: TableColumn) => {
  // TODO: 实现筛选功能
  console.log("Show filter for column:", column.key);
};

const handleSelectAll = (event: Event) => {
  const target = event.target as HTMLInputElement;

  if (target.checked) {
    // 选中当前页所有行
    paginatedData.value.forEach((row) => {
      if (!isRowSelected(row)) {
        selectedRows.value.push(row);
      }
    });
  } else {
    // 取消选中当前页所有行
    paginatedData.value.forEach((row) => {
      const index = selectedRows.value.findIndex(
        (selectedRow) => getRowKey(selectedRow, 0) === getRowKey(row, 0),
      );
      if (index > -1) {
        selectedRows.value.splice(index, 1);
      }
    });
  }

  emit("select", selectedRows.value);
};

const handleRowSelect = (row: any, event: Event) => {
  const target = event.target as HTMLInputElement;

  if (target.checked) {
    selectedRows.value.push(row);
  } else {
    const index = selectedRows.value.findIndex(
      (selectedRow) => getRowKey(selectedRow, 0) === getRowKey(row, 0),
    );
    if (index > -1) {
      selectedRows.value.splice(index, 1);
    }
  }

  emit("select", selectedRows.value);
};

const clearSelection = () => {
  selectedRows.value = [];
  emit("select", selectedRows.value);
};

const handleRowClick = (row: any, index: number) => {
  emit("rowClick", row, index);
};

const handleRowDoubleClick = (row: any, index: number) => {
  emit("rowDoubleClick", row, index);
};

const handlePageChange = (page: number) => {
  if (page < 1 || page > totalPages.value) return;

  currentPage.value = page;
  emit("pageChange", page);
};

const toggleColumn = (columnKey: string) => {
  const index = hiddenColumns.value.indexOf(columnKey);
  if (index > -1) {
    hiddenColumns.value.splice(index, 1);
  } else {
    hiddenColumns.value.push(columnKey);
  }
};

// 监听
watch(
  () => props.sortBy,
  (newSortBy) => {
    if (newSortBy) {
      currentSort.value.column = newSortBy;
    }
  },
);

watch(
  () => props.sortOrder,
  (newSortOrder) => {
    if (newSortOrder) {
      currentSort.value.order = newSortOrder;
    }
  },
);

// 公开方法
const getSelectedRows = () => selectedRows.value;
const clearSort = () => {
  currentSort.value = { column: "", order: null };
};
const clearFilters = () => {
  filters.value = {};
};

defineExpose({
  getSelectedRows,
  clearSelection,
  clearSort,
  clearFilters,
});
</script>

<style scoped>
/* 表格容器 */
.table-container {
  background-color: var(--bg-color);
  border-radius: 8px;
  overflow: hidden;
}

/* 工具栏 */
.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
}

.table-toolbar-left {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
}

.table-toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.table-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}

.table-description {
  margin: 0;
  font-size: 14px;
  color: var(--text-secondary);
}

.table-selection-info {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text-secondary);
}

/* 表格包装器 */
.table-wrapper {
  overflow-x: auto;
  overflow-y: hidden;
}

.table-wrapper::-webkit-scrollbar {
  height: 8px;
}

.table-wrapper::-webkit-scrollbar-track {
  background: var(--bg-secondary);
}

.table-wrapper::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 4px;
}

/* 表格 */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.table.table-bordered {
  border: 1px solid var(--border-color);
}

.table.table-bordered .table-cell {
  border: 1px solid var(--border-color);
}

/* 表头 */
.table-header {
  background-color: var(--bg-tertiary);
}

.table-cell-header {
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
}

.table-header-content {
  display: flex;
  align-items: center;
  gap: 4px;
}

.table-header-title {
  flex: 1;
}

.table-sort-icon {
  opacity: 0.5;
  transition: opacity 0.2s ease;
}

.table-cell-sortable {
  cursor: pointer;
  user-select: none;
}

.table-cell-sortable:hover .table-sort-icon {
  opacity: 1;
}

.table-sort-icon.active {
  opacity: 1;
  color: var(--primary-color);
}

.table-filter-icon {
  opacity: 0.5;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.table-filter-icon:hover,
.table-filter-icon.active {
  opacity: 1;
  color: var(--primary-color);
}

/* 表格单元格 */
.table-cell {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-color);
  vertical-align: middle;
}

.table-cell-left {
  text-align: left;
}

.table-cell-center {
  text-align: center;
}

.table-cell-right {
  text-align: right;
}

.table-cell-ellipsis {
  max-width: 200px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.table-cell-selection {
  width: 48px;
  text-align: center;
}

.table-cell-index {
  width: 60px;
  text-align: center;
  color: var(--text-secondary);
}

.table-cell-actions {
  width: 120px;
  text-align: center;
}

/* 表格行 */
.table-row {
  transition: background-color 0.2s ease;
}

.table-row:hover {
  background-color: var(--hover-bg);
}

.table-row-selected {
  background-color: rgba(var(--primary-color-rgb), 0.1);
}

.table-row-striped {
  background-color: var(--bg-secondary);
}

/* 复选框 */
.table-checkbox {
  width: 16px;
  height: 16px;
  cursor: pointer;
}

/* 操作按钮 */
.table-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

/* 加载状态 */
.table-loading-cell {
  padding: 40px;
  text-align: center;
}

/* 空状态 */
.table-empty-cell {
  padding: 40px;
  text-align: center;
}

.table-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.table-empty-icon {
  color: var(--text-tertiary);
}

.table-empty-text {
  margin: 0;
  color: var(--text-secondary);
  font-size: 14px;
}

/* 分页 */
.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-top: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
}

.table-pagination-info {
  font-size: 14px;
  color: var(--text-secondary);
}

.table-pagination-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.table-pagination-pages {
  display: flex;
  gap: 4px;
}

/* 列设置 */
.column-settings {
  max-height: 300px;
  overflow-y: auto;
}

.column-setting-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
}

.column-setting-item input {
  width: 16px;
  height: 16px;
}

/* 尺寸变体 */
.table-mini .table-cell {
  padding: 8px 12px;
  font-size: 12px;
}

.table-small .table-cell {
  padding: 10px 14px;
  font-size: 13px;
}

.table-large .table-cell {
  padding: 16px 20px;
  font-size: 15px;
}

/* 固定列 */
.table-cell-fixed-left {
  position: sticky;
  left: 0;
  z-index: 10;
  background-color: inherit;
}

.table-cell-fixed-right {
  position: sticky;
  right: 0;
  z-index: 10;
  background-color: inherit;
}

/* 响应式 */
@media (max-width: 768px) {
  .table-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .table-toolbar-left,
  .table-toolbar-right {
    justify-content: space-between;
  }

  .table-pagination {
    flex-direction: column;
    gap: 12px;
  }

  .table-pagination-controls {
    flex-wrap: wrap;
    justify-content: center;
  }

  .table-cell {
    padding: 8px 12px;
    font-size: 13px;
  }
}

@media (max-width: 480px) {
  .table-toolbar {
    padding: 12px 16px;
  }

  .table-pagination {
    padding: 12px 16px;
  }

  .table-cell {
    padding: 6px 8px;
    font-size: 12px;
  }

  .table-cell-ellipsis {
    max-width: 120px;
  }
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .table-row:hover {
    background-color: rgba(255, 255, 255, 0.05);
  }

  .table-row-selected {
    background-color: rgba(var(--primary-color-rgb), 0.2);
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  .table {
    border: 2px solid var(--text-primary);
  }

  .table-cell {
    border-color: var(--text-primary);
  }
}
</style>
